package com.sjq.common.dao;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.sql.Clob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

/**
 * @ClassName: GenericDao
 * @Description: DAO层基类
 * @author 张剑
 */
public abstract class GenericDao<T> {
	
	//Logger logger = Logger.getLogger(MenuTreeRestController.class);
	
	private JdbcTemplate jdbcTemplate;
	private NamedParameterJdbcTemplate namedParameterJdbcTemplate;



	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}
    @Resource
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
    
	public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
		return namedParameterJdbcTemplate;
	}
	
	@Resource
	public void setNamedParameterJdbcTemplate(
			NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
		this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
	}
	
	
	public List<Map<String, Object>> getListBySqlOnNamedParameterJdbcTemplate(String sql,Map params) throws SQLException {
		
		List<Map<String,Object>> results = this.getNamedParameterJdbcTemplate().query(sql, params, new RowMapper<Map<String,Object>>() {
			
			public Map<String,Object> mapRow(ResultSet rs, int i) throws SQLException {
				ResultSetMetaData m = rs.getMetaData();
				int colCount = m.getColumnCount();
				
				Map<String,Object> row = new HashMap<String,Object>();
				
				for (int colNum = 1; colNum <= colCount; colNum++) {
					if (m.getColumnType(colNum) == Types.CLOB) {//处理Clob
						row.put(m.getColumnName(colNum).toLowerCase(), clobToString(rs.getClob(colNum)));
					} else {
						row.put(m.getColumnName(colNum).toLowerCase(), rs.getString(colNum));
					}
				}
				
				return row;
			}
		});
		return results;
	}
	
	public List<Map<String, String>> getListBySql(String sql,Object[] param) throws SQLException {
		List<Map<String,String>> results = this.getJdbcTemplate().query(sql, param, new RowMapper<Map<String,String>>() {
			@Override
			public Map<String,String> mapRow(ResultSet rs, int i) throws SQLException {
				ResultSetMetaData m = rs.getMetaData();
				int colCount = m.getColumnCount();
				
				Map<String,String> row = new HashMap<String,String>();
				
				for (int colNum = 1; colNum <= colCount; colNum++) {
					if (m.getColumnType(colNum) == Types.CLOB) {//处理Clob
						row.put(m.getColumnName(colNum).toLowerCase(), clobToString(rs.getClob(colNum)));
					} else {
						String sj="";
						if(rs.getString(colNum)==null){
							sj="";
						}else {
							sj=rs.getString(colNum);
						}
						row.put(m.getColumnName(colNum).toLowerCase(), sj);
					}
				}
				
				return row;
			}
		});
		return results;
	}
	
	
	
	
	public Map<String, Object> getMapBySql(String sql,Object[] param) throws SQLException {
		Map<String,Object> srs = this.getJdbcTemplate().queryForMap(sql, param);
		return srs;
	}
	
	public Map<String, String> getStringMapBySql(String sql,Object[] param) throws SQLException {
		Map<String,String> sr = this.getJdbcTemplate().queryForObject(sql, param,new RowMapper<Map<String,String>>() {
			@Override
			public Map<String,String> mapRow(ResultSet rs, int i) throws SQLException {
				ResultSetMetaData m = rs.getMetaData();
				int colCount = m.getColumnCount();
				
				Map<String,String> row = new HashMap<String,String>();
				
				for (int colNum = 1; colNum <= colCount; colNum++) {
					if (m.getColumnType(colNum) == Types.CLOB) {//处理Clob
						row.put(m.getColumnName(colNum).toLowerCase(), clobToString(rs.getClob(colNum)));
					} else {
						row.put(m.getColumnName(colNum).toLowerCase(), rs.getString(colNum));
					}
				}
				
				return row;
			}
		});
		return sr;
	}
	
	private String clobToString(Clob c) throws SQLException {
		if (null == c) {
			return null;
		}
		Reader reader = c.getCharacterStream();
		BufferedReader br = new BufferedReader(reader);
		StringBuffer sb = new StringBuffer();
		String line = null;
		try {
			while (null != (line = br.readLine())) {
				sb.append(line);
			}
		}catch (Exception e) {
			//logger.error("Clob转String 异常:",e);
		} finally {
			try {
				br.close();
				reader.close();
			} catch (IOException e) {
			//	logger.error("Clob转String 异常-流关闭异常:",e);
			} finally {
			}
		}
		return sb.toString();
	}
	
	public void update(String sql,Object[] param) throws SQLException {
		this.getJdbcTemplate().update(sql, param);
	}
	
	protected void batchUpdate(String sql,final List<List<String>> paramList){
		this.getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {
			@Override
			public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {
				List<String> params = paramList.get(i);
				for(int j=0;j<params.size();j++){
					preparedStatement.setString(j+1,params.get(j));
				}
			}
			
			@Override
			public int getBatchSize() {
				return paramList.size();
			}
		});
	}
}
